import json
import sys



import jieba

from py2neo import Graph
import re

class Neo4jNerService:
    def __init__(self):

#         self.graph = Graph("http://localhost:8848", auth=("test", "ljq123456"),name="neo4j")
        self.graph = Graph("http://localhost:7474", auth=("neo4j", "111111"))
    def find_similar_locations(self, text):

        print(11111111111111111)
        text = text.replace('。', '，')


        # 身份证号
        id_number_pattern = [
            r"身份证号是(\d{18})，",
            r"身份证号码是(\d{18})，",
            r"我的身份证号是(\d{18})，",
            r"我的身份证号码是(\d{18})，",
            r"身份证号码为(\d{18})，",
            r"身份证号为(\d{18})，",
            r"身份证号码(\d{18})，",
            r"身份证号(\d{18})，",
        ]

        # 姓名
        name_pattern = [
            r"我叫(.*?)，",
            r"姓名是(.*?)，",
            r"名字是(.*?)，",
            r"我的名字是(.*?)，",
            r"我是(.*?)，",
            r"名字叫(.*?)，",
        ]

        # 民族
        ethnicity_pattern = [
            r"民族是(.*?)，",
            r"我的民族是(.*?)，",
            r"我是(.*?)族，"
        ]

        # 政治面貌
        political_status_pattern = [
            r"政治面貌是(.*?)，",
            r"我的政治面貌是(.*?)，",
            r"政治身份是(.*?)，"
        ]

        # 专科院校
        college_pattern = [
            r"专科院校是(.*?)，",
            r"专科学校是(.*?)，",
            r"专科学校为(.*?)，",
            r"专科院校为(.*?)，"
        ]

        # 专科专业
        specialty_pattern = [
            r"专科专业是(.*?)，",
            r"我的专科专业是(.*?)，"
        ]

        # 报名号
        registration_number_pattern = [
            r"报名号是(.*?)，",
            r"我的报名号是(.*?)，",
            r"报名编号是(.*?)，",
            r"报名编号为(.*?)，",
            r"报名号码是(.*?)，",
        ]


        # 考生号
        examinee_number_pattern = [
            r"考生号是(.*?)，",
            r"我的考生号是(.*?)，",
            r"考生编号是(.*?)，",
            r"考生编号为(.*?)，",
            r"考生号为(.*?)，"
        ]

        # 通知书邮寄地址
        address_pattern = [
            #r"给给给(.*?)，"
            r"通知书邮寄地址是(.*?)，",
            r"邮寄地址是(.*?)，",
            r"通知书邮寄地址为(.*?)，"
        ]

        # 通知书收件人
        recipient_pattern = [
            r"通知书收件人是(.*?)，",
            r"收件人是(.*?)，",
            r"通知书收件人为(.*?)，"
        ]

        # 邮编
        postal_code_pattern = [
            r"邮编是(.*?)，",
            r"邮政编码是(.*?)，",
            r"邮政编码为(.*?)，",
            r"我的邮编是(.*?)，"
        ]

        # 外语语种
        foreign_language_pattern = [
            r"外语语种是(.*?)，",
            r"外语是(.*?)，",
            r"外语语种为(.*?)，",
            r"我的外语种是(.*?)，",
            r"外语种是(.*?)，"
        ]

        # 考点盟市
        exam_city_pattern = [
            r"考点盟市(.*?)，",
            r"考点门市是(.*?)，",
            r"考试地点是(.*?)，",
            r"考点门市(.*?)，",
            r"考点盟市是(.*?)，",
            r"考点模式是(.*?)，",
        ]

        # 报考专业
        exam_specialty_pattern = [
            r"报考专业是(.*?)，",
            r"报考专业为(.*?)，",
            r"报考的专业是(.*?)，",
            r"报考的专科专业是(.*?)，"
        ]

        # 志愿院校
        wish_college_pattern = [
            r"志愿院校是(.*?)，",
            r"志愿院校为(.*?)，",
            r"我的志愿院校是(.*?)，"
        ]

        # 志愿专业
        wish_specialty_pattern = [
            r"志愿专业是(.*?)，",
            r"报考专业是(.*?)，",
            r"我的志愿专业是(.*?)，",
            r"志愿专业为(.*?)，"
        ]
        # 电话
        phone_pattern = [
            r"电话号码是(.*?)，",
            r"电话号是(.*?)，",
            r"电话是(.*?)，",
            r"电话为(.*?)，"
        ]

        # 密码
        password_pattern = [
            r"密码是(.*?)，",
            r"密码为(.*?)，"
        ]

        # 确认状态
        is_certificate_issued_pattern = [
            r"我的证书状态是(.*?)，",
            r"我的证书状态为(.*?)，"
        ]

        # 定义正则表达式模式
        patterns = {
            "id_number": id_number_pattern,
            "name": name_pattern,
            "ethnicity": ethnicity_pattern,
            "political_status": political_status_pattern,
            "college": college_pattern,
            "specialty": specialty_pattern,
            "registration_number": registration_number_pattern,
            "examinee_number": examinee_number_pattern,
            "address": address_pattern,
            "recipient": recipient_pattern,
            "postal_code": postal_code_pattern,
            "foreign_language": foreign_language_pattern,
            "exam_city": exam_city_pattern,
            "exam_specialty": exam_specialty_pattern,
            "wish_college": wish_college_pattern,
            "wish_specialty": wish_specialty_pattern,
            "phone": phone_pattern,
            "password": password_pattern,
            "is_certificate_issued": is_certificate_issued_pattern
        }

        # 提取信息
        info = self.extract_info(text, patterns)
        id_number=info['id_number']
        name = info['name']
        ethnicity = info['ethnicity']
        if ethnicity!="未知":
            query_ethnicity = f"""
                MATCH (c:Minzu)
                WITH '{ethnicity}' AS inputText, c
                ORDER BY apoc.text.levenshteinDistance(inputText, c.name) ASC
                LIMIT 1
                RETURN c.name, apoc.text.levenshteinDistance(inputText, c.name) AS distance
                """
            ethnicity = self.graph.run(query_ethnicity).data()
            ethnicity = ethnicity[0]['c.name']  # 提取查询结果中的 name 属性
        else:
            ethnicity = "未知"
        political_status = info['political_status']
        if political_status!="未知":
            query_political_status = f"""
                MATCH (c:Zhengzhimianmao)
                WITH '{political_status}' AS inputText, c
                ORDER BY apoc.text.levenshteinDistance(inputText, c.name) ASC
                LIMIT 1
                RETURN c.name, apoc.text.levenshteinDistance(inputText, c.name) AS distance
                """
            political_status = self.graph.run(query_political_status).data()
            political_status = political_status[0]["c.name"]
        else:
            political_status = "未知"
        college = info['college']
        specialty = info['specialty']
        registration_number = info['registration_number']
        examinee_number = info['examinee_number']
        address = info['address']
        print("address:"+address)
        recipient = info['recipient']
        postal_code = info['postal_code']
        foreign_language = info['foreign_language']
        if foreign_language!="未知":
            query_foreign_language = f"""
                MATCH (c:Waiyuyuzhong)
                WITH '{foreign_language}' AS inputText, c
                ORDER BY apoc.text.levenshteinDistance(inputText, c.name) ASC
                LIMIT 1
                RETURN c.name, apoc.text.levenshteinDistance(inputText, c.name) AS distance
                """
            foreign_language = self.graph.run(query_foreign_language).data()
            foreign_language = foreign_language[0]['c.name']  # 提取查询结果中的 name 属性
        else:
            foreign_language = "未知"

        exam_city = info['exam_city']
        if exam_city!="未知":
            query_exam_city = f"""
                MATCH (c:Kaodianmengzhi)
                WITH '{exam_city}' AS inputText, c
                ORDER BY apoc.text.levenshteinDistance(inputText, c.name) ASC
                LIMIT 1
                RETURN c.name, apoc.text.levenshteinDistance(inputText, c.name) AS distance
                """
            exam_city = self.graph.run(query_exam_city).data()
            exam_city = exam_city[0]['c.name']  # 提取查询结果中的 name 属性
        else:
            exam_city = "未知"

        exam_specialty = info['exam_specialty']
        wish_college = info['wish_college']
        wish_specialty = info['wish_specialty']
        phone = info['phone']
        password = info['password']
        is_certificate_issued = info['is_certificate_issued']

        # 模糊匹配 is_certificate_issued 字段
        if "已获得" in is_certificate_issued or "已经" in is_certificate_issued:
            is_certificate_issued = 1
        elif "未获得" in is_certificate_issued or "未" in is_certificate_issued or "没有" in is_certificate_issued or "没" in is_certificate_issued:
            is_certificate_issued = 0
        else:
            is_certificate_issued = 2
        print("wish_college:"+wish_college)
        print("wish_specialty:"+wish_specialty)



        # 提取出生日期和性别
        if len(id_number) == 18:
            birth_date = id_number[6:14]  # 提取出生日期
            birth_date = f"{birth_date[:4]}-{birth_date[4:6]}-{birth_date[6:8]}"  # 格式化为 YYYY-MM-DD
            gender_code = int(id_number[16])  # 提取性别码
            gender = "男" if gender_code % 2 != 0 else "女"  # 判断性别
        else:
            birth_date = "未知"
            gender = "未知"

        print("college:"+college)
        if college!="未知":

            # 查询相似的专科院校
            query_college = f"""
                    MATCH (c:Zhuankeyuanxiao)
                    WITH '{college}' AS inputText, c
                    ORDER BY apoc.text.levenshteinDistance(inputText, c.name) ASC
                    LIMIT 1
                    RETURN c.name, apoc.text.levenshteinDistance(inputText, c.name) AS distance
                    """
            college = self.graph.run(query_college).data()
            college = college[0]['c.name']  # 提取查询结果中的 name 属性
        else:
            college = "未知"
        if specialty!="未知":
            # 查询相似的专科专业
            query_specialty = f"""
                    MATCH (c:Zhuankeyuanxiao)-[:rels_schoolAndMajor]->(s:Zhuankezhuanye)
                    WHERE c.name = '{college}'
                    WITH '{specialty}' AS inputText, s
                    ORDER BY apoc.text.levenshteinDistance(inputText, s.name) ASC
                    LIMIT 1
                    RETURN s.name, apoc.text.levenshteinDistance(inputText, s.name) AS distance
                    """
            specialty = self.graph.run(query_specialty).data()
            specialty = specialty[0]['s.name']  # 提取查询结果中的 name 属性
        else:
            specialty = "未知"


        if wish_college!="未知":
            # 查询相似的志愿院校
            query_wish_college = f"""
                    MATCH (c:Zhiyuanyuanxiao)
                    WITH '{wish_college}' AS inputText, c
                    ORDER BY apoc.text.levenshteinDistance(inputText, c.name) ASC
                    LIMIT 1
                    RETURN c.name, apoc.text.levenshteinDistance(inputText, c.name) AS distance
                    """
            wish_college = self.graph.run(query_wish_college).data()
            wish_college = wish_college[0]['c.name']  # 提取查询结果中的 name 属性
        else:
            wish_college = "未知"

        if wish_specialty!="未知":

            # 查询相似的志愿专业
            query_wish_specialty = f"""
                    MATCH (c:Zhiyuanyuanxiao)-[:rels_wantToGoschoolAndMajor]->(s:Zhiyuanzhuanye)
                    WHERE c.name = '{wish_college}'
                    WITH '{wish_specialty}' AS inputText, s
                    ORDER BY apoc.text.levenshteinDistance(inputText, s.name) ASC
                    LIMIT 1
                    RETURN s.name, apoc.text.levenshteinDistance(inputText, s.name) AS distance
                    """
            wish_specialty = self.graph.run(query_wish_specialty).data()
            wish_specialty = wish_specialty[0]['s.name']  # 提取查询结果中的 name 属性
        else:
            wish_specialty = "未知"

        # 初始化一个空字符串用于存储合并后的地名
        full_address = ""
        if address=="未知":
            full_address="未知"
        else:
            print(666)
            # 精确模式，试图将句子最精确地切开，适合文本分析
            seg_list = jieba.cut(address, cut_all=False)
            result = "/".join(seg_list)
            lst = result.split("/")
            if len(lst[2:3]) > 0:
                if '街' in lst[4] and '街' not in lst[3]:
                    # 合并[4]号索引项和[3]号索引项
                    lst[3] = f'{lst[3]}{lst[4]}'
            # 合并其后的所有索引项成一项
            lst[4:] = [''.join(lst[5:])]
            #print(add_results)
            locations = []
            address_list = []
            for entity in lst:  # results[0] 是一个包含实体信息的列表
                locations.append(entity)  # entity[0] 是实体的文本

            query0 = f"""
                        MATCH (n:Province)
                        WHERE n.name IS NOT NULL
                        WITH '{locations[0]}' AS inputText, n
                        ORDER BY apoc.text.levenshteinDistance(inputText, n.name) ASC
                        LIMIT 1
                        RETURN n.name, apoc.text.levenshteinDistance(inputText, n.name) AS distance
                        """
            result0 = self.graph.run(query0).data()
            province_name = result0[0].get("n.name") if result0 else "xx省"
            query1 = f"""
                MATCH (p:Province)-[:CONTAINS]->(c:City)
                WHERE p.name = '{province_name}'
                WITH '{locations[1]}' AS inputText, c
                ORDER BY apoc.text.levenshteinDistance(inputText, c.name) ASC
                LIMIT 1
                RETURN c.name, apoc.text.levenshteinDistance(inputText, c.name) AS distance
                """
            result1 = self.graph.run(query1).data()
            city_name = result1[0].get("c.name") if result1 else "xx市"
            query2 = f"""
                MATCH (c:City)-[:CONTAINS]->(d:County)
                WHERE c.name = '{city_name}'
                WITH '{locations[2]}' AS inputText, d
                ORDER BY apoc.text.levenshteinDistance(inputText, d.name) ASC
                LIMIT 1
                RETURN d.name, apoc.text.levenshteinDistance(inputText, d.name) AS distance
                """
            result2 = self.graph.run(query2).data()
            county_name = result2[0].get("d.name") if result2 else "xx区县"
            query3 = f"""
                MATCH (d:County)-[:CONTAINS]->(e:Block)
                WHERE d.name = '{county_name}'
                WITH '{locations[3]}' AS inputText, e
                ORDER BY apoc.text.levenshteinDistance(inputText, e.name) ASC
                LIMIT 1
                RETURN e.name, apoc.text.levenshteinDistance(inputText, e.name) AS distance
                """
            result3 = self.graph.run(query3).data()
            block_name = result3[0].get("e.name") if result3 else "xx街道"
            query4 = f"""
                MATCH (e:Block)-[:CONTAINS]->(f:Town)
                WHERE e.name = '{block_name}'
                WITH '{locations[4]}' AS inputText, f
                ORDER BY apoc.text.levenshteinDistance(inputText, f.name) ASC
                LIMIT 1
                RETURN f.name, apoc.text.levenshteinDistance(inputText, f.name) AS distance
                """
            result4 = self.graph.run(query4).data()
            town_name = result4[0].get("f.name") if result4 else "xx小区"


            #合并地名
            if province_name:
                full_address += province_name
            if city_name:
                full_address += city_name
            if county_name:
                full_address += county_name
            if block_name:
                full_address += block_name
            if town_name:
                full_address += town_name
            # print("full_address:"+full_address)
            print("full_address:"+full_address)
        # # 精确模式，试图将句子最精确地切开，适合文本分析
        # seg_list = jieba.cut(address, cut_all=False)
        # result = "/".join(seg_list)
        # lst = result.split("/")
        #
        # if '街' in lst[4] and '街' not in lst[3]:
        #     # 合并[4]号索引项和[3]号索引项
        #     lst[3] = f'{lst[3]}{lst[4]}'
        #     # 合并其后的所有索引项成一项
        #     lst[4:] = [''.join(lst[5:])]
        # #print(add_results)
        # locations = []
        # address_list = []
        # for entity in lst:  # results[0] 是一个包含实体信息的列表
        #     locations.append(entity)  # entity[0] 是实体的文本





        entitys = {
            "id_number": id_number,
            "name": name,
            "birth_date": birth_date,
            "gender": gender,
            "ethnicity": ethnicity,
            "political_status": political_status,
            "vocational_college":college,
            "vocational_major": specialty,
            "registration_number": registration_number,
            "examinee_number": examinee_number,
            "address": full_address,
            "recipient_name": recipient,
            "postal_code": postal_code,
            "foreign_language": foreign_language,
            "exam_center_city": exam_city,
            "exam_major": exam_specialty,
            "volunteer_college": wish_college,
            "volunteer_major": wish_specialty,
            "postal_code": postal_code,
            "phone": phone,
            "password": password,
            "is_certificate_issued": is_certificate_issued
        }

        return json.dumps(entitys, ensure_ascii=False)

    @staticmethod
    def extract_info(text, patterns):
        result = {}
        for key, pattern_list in patterns.items():
            for pattern in pattern_list:
                match = re.search(pattern, text)
                if match:
                    result[key] = match.group(1).strip()
                    print(f"{key}: {result[key]}")
                    break
            else:
                result[key] = "未知"  # 如果没有匹配到，设置默认值
        return result

# 使用示例
if __name__ == "__main__":
    java_string = sys.argv[1]
    #java_string = input("Please input the text: ")
    #print(f"Received from Java: {java_string}")
    service = Neo4jNerService()
    text = "我叫张小奔，我的民族是汉族，我的政治面貌是群众，我的专科院校是内蒙古师范大学专科。我的专科专业是云计算技术应用，我的报名号是026431。我的考生号是2415。我的通知书邮寄地址是内蒙古自治区呼和浩特市赛罕区大学东街翻斗花园，我的通知书收件人是张永贵，邮编是013350，我的外语语种是英语，我的考点模式是呼和浩特市，我的报考专业是计算机科学与技术。我的志愿院校是内蒙古工业大学，我的志愿专业是数据科学与大数据技术，身份证号码150104199109251617。电话号码是12345678956，密码是8749，确认状态为已确认。"
    result = service.find_similar_locations(java_string)
    #re = json.loads(result)
    print(result)
